#include "SENSOR/sensor_app.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/**
 ****************************************************************************************************
 * DONE 用户变量区
 ****************************************************************************************************
 */

SensorData ADC_Data;

double temperature;
float distance;
double water_sample;

/**
 ****************************************************************************************************
 * 驱动函数区
 ****************************************************************************************************
 */

//数据映射
double sensor_map(uint16_t map_val,uint16_t in_min,uint16_t in_max,uint16_t out_min,uint16_t out_max)
{
    // 边界保护 
    if (map_val <= in_min) return out_min;
    if (map_val >= in_max) return out_max;
    // 线性计算 
    return (map_val - in_min) * (out_max - out_min) *1.0/ (in_max - in_min) *1.0+ out_min;
}

//水上
//烟雾传感器MQ-2        5v
double sensor_map_smog(uint16_t smog)
{
#if SENSOR_MAP_MODE == 1
    double Vol = (smog*5/4096);
	double RS = (5-Vol)/(Vol*4.7);
	double R0=6.64;
	
	double MQ_2_DAT = pow(11.5428*R0/RS, 0.6549f);

    return MQ_2_DAT;
#elif SENSOR_MAP_MODE == 2
    double MQ_2_DAT = sensor_map(smog,0,4095,300,10000);

    return MQ_2_DAT;
#else
    return smog;
#endif
}

//乙醇传感器MQ-3        5v
double sensor_map_ethyl_alcohol(uint16_t ethyl_alcohol)
{
#if SENSOR_MAP_MODE == 1
    double Vol = (ethyl_alcohol*5/4096);
	double RS = (5-Vol)/(Vol*0.5);
	double R0=6.64;
	
	double MQ_3_DAT = pow(11.5428*R0/RS, 0.6549f);

    return MQ_3_DAT;
#elif SENSOR_MAP_MODE == 2
    double MQ_3_DAT = sensor_map(ethyl_alcohol,0,4095,25,500);

    return MQ_3_DAT;
#else
    return ethyl_alcohol;
#endif
}

//一氧化碳传感器MQ-7        5v
double sensor_map_carbon_monoxide(uint16_t carbon_monoxide)
{
#if SENSOR_MAP_MODE == 1
    double Vol = (carbon_monoxide*5/4096);
	double RS = (5-Vol)/(Vol*0.5);
	double R0=6.64;
	
	double MQ_7_DAT = pow(11.5428*R0/RS, 0.6549f);

    return MQ_7_DAT;
#elif SENSOR_MAP_MODE == 2
    double MQ_7_DAT = sensor_map(carbon_monoxide,0,4095,10,1000);

    return MQ_7_DAT;
#else
    return carbon_monoxide;
#endif
}

//可燃气体传感器MQ-5        5v
double sensor_map_combustible_gas(uint16_t combustible_gas)
{
#if SENSOR_MAP_MODE == 1
    double Vol = (combustible_gas*5/4096);
	double RS = (5-Vol)/(Vol*0.5);
	double R0=6.64;
	
	double MQ_5_DAT = pow(11.5428*R0/RS, 0.6549f);

    return MQ_5_DAT;
#elif SENSOR_MAP_MODE == 2
    double MQ_5_DAT = sensor_map(combustible_gas,0,4095,300,10000);

    return MQ_5_DAT;
#else  
    return combustible_gas;
#endif 
}

//超声波传感器        5v

void sensor_Distance(void)
{
    distance = UltrasonicGetLength();
}

//

//水下
//电导率传感器        3v3/5v
double sensor_map_conductivity(uint16_t smconductivityog)
{
#if SENSOR_MAP_MODE == 1
    double TDS_DAT;
    TDS_DAT = (smconductivityog/4095.0)*5;//转换为电压值
	TDS_DAT = 66.71*TDS_DAT*TDS_DAT*TDS_DAT-127.93*TDS_DAT*TDS_DAT+428.7*TDS_DAT;//转换为PPM值
	
    if(TDS_DAT<20) TDS_DAT = 0;
    
    return TDS_DAT;
#elif SENSOR_MAP_MODE == 2
    double TDS_DAT;
    TDS_DAT = (smconductivityog/4095.0)*5;//转换为电压值
	TDS_DAT = 66.71*TDS_DAT*TDS_DAT*TDS_DAT-127.93*TDS_DAT*TDS_DAT+428.7*TDS_DAT;//转换为PPM值
	
    if(TDS_DAT<20) TDS_DAT = 0;
    
    return TDS_DAT;
#else  
    return smconductivityog;
#endif 
}

//浊度传感器        5v
double sensor_map_turbidity(uint16_t turbidity)
{
#if SENSOR_MAP_MODE == 1
    double TS_DAT;
	TS_DAT = (turbidity/4096.0)*5;//转换为电压值
	TS_DAT = -865.68*TS_DAT+TS_K;//转换为PPM值

	if(TS_DAT<35) TS_DAT = 0;
    
    return TS_DAT;
#elif SENSOR_MAP_MODE == 2
    double TS_DAT;
	TS_DAT = (turbidity/4096.0)*5;//转换为电压值
	TS_DAT = -865.68*TS_DAT+TS_K;//转换为PPM值

	if(TS_DAT<25) TS_DAT = 0;
    
    return TS_DAT;
#else  
    return turbidity;
#endif 
}

//PH酸碱度传感器        5v
double sensor_map_pH_value(uint16_t pH_value)
{
#if SENSOR_MAP_MODE == 1
    double PH_DAT;
	PH_DAT = (pH_value/4096.0)*5;//转换为电压值
	PH_DAT = -5.7541*PH_DAT+16.654;//转换为PPM值
	
	if(PH_DAT>14.0)PH_DAT=14.0;
	if(PH_DAT<0)PH_DAT=0.0;

    return PH_DAT;
#elif SENSOR_MAP_MODE == 2
    double PH_DAT;
	PH_DAT = (pH_value/4096.0)*5;//转换为电压值
	PH_DAT = -5.942*PH_DAT+16.420;//转换为PPM值
	
	if(PH_DAT>14.0)PH_DAT=14.0;
	if(PH_DAT<0)PH_DAT=0.0;

    return PH_DAT;
#else  
    return pH_value;
#endif 
}

//水压深度传感器
uint16_t sensor_map_depth(uint16_t depth)
{
#if SENSOR_MAP_MODE == 1
    return depth;
#elif SENSOR_MAP_MODE == 2
    return depth;
#else  
    return depth;
#endif 
}

//DS18B20水温        5v
void sensor_GetTemperature(void)
{
    temperature = DS18B20_Get_Temp();
}
//

/**
 ****************************************************************************************************
 * DONE 用户函数区
 ****************************************************************************************************
 */

 /**
  * @name 传感器初始化函数
  * @brief 对部分传感器的初始化（DS18B20、超声波）
  * @param 无
  * @result 无
  */
void sensor_Init(void)
{
    USART_printf(Test_huart,DS18B20_Init() > 0 ? "DS18B20 ERRER\r\n" : "DS18B20 OK\r\n");
    // Ultrasonic_Init();
}



#if ADC_READ_MODE == 0
void ReadAndProcessAllSensors(ADC_HandleTypeDef* hadc) 
{
    // 遍历8个ADC通道
    for (uint8_t channel = 0; channel < 8; channel++) {
        // 读取原始ADC值
        uint16_t raw_adc = ADC_Read(hadc);  // 调用ADC采集程序
        ADC_Data.adc_raw[channel] = raw_adc;

        // 第一级滤波
        uint16_t filtered_adc_1 = ADCgetavg1(raw_adc);

        // 第二级滤波
        uint16_t filtered_adc_2 = ADCgetavg2(filtered_adc_1);

        // 存储滤波后的ADC值
        ADC_Data.adc_filtered[channel] = filtered_adc_1;

        // 将滤波后的ADC值转换为电压值（单位：mV）
        ADC_Data.voltage[channel] = ADC_to_Voltage(filtered_adc_1);
    }
}

#elif ADC_READ_MODE == 1

void ReadAndProcessAllSensors_DMA(uint16_t dmaBuffer[]) 
{

    for (uint8_t channel = 0; channel < ADC1_CHANNEL_CNT; channel++) 
    {
        uint16_t raw_adc;
        raw_adc = (uint16_t)dmaBuffer[channel];
        // 当前数据
        ADC_Data.adc_new[channel] = raw_adc;
        
        // 存储原始平均值到全局变量
        ADC_Data.adc_raw[channel] = raw_adc;
        // 第一级滤波
        uint16_t filtered_adc_1 = ADCgetavg1(raw_adc);
        // 第二级滤波
        uint16_t filtered_adc_2 = ADCgetavg2(filtered_adc_1);
        // 存储滤波后的数据到全局变量
        ADC_Data.adc_filtered[channel] = filtered_adc_1;
        // 转换为电压值
        ADC_Data.voltage[channel] = ADC_to_Voltage(raw_adc);
    }
    //PH值
    ADC_Data.adc_map[0]= sensor_map_pH_value(ADC_Data.adc_raw[0]);
    //电导率
    ADC_Data.adc_map[1]= sensor_map_conductivity(ADC_Data.adc_raw[1]);
    //浊度
    ADC_Data.adc_map[2]= sensor_map_turbidity(ADC_Data.adc_raw[2]);
    //烟雾2
    ADC_Data.adc_map[3]= sensor_map_smog(ADC_Data.adc_raw[3]);
    //乙醇3
    ADC_Data.adc_map[4]= sensor_map_ethyl_alcohol(ADC_Data.adc_raw[4]);
    //一氧化碳7
    ADC_Data.adc_map[5]= sensor_map_carbon_monoxide(ADC_Data.adc_raw[5]);
    //可燃气体5              
    ADC_Data.adc_map[6]= sensor_map_combustible_gas(ADC_Data.adc_raw[6]);
    //液位
    ADC_Data.adc_map[7]= sensor_map_depth(ADC_Data.adc_raw[7]);
}

#elif ADC_READ_MODE == 2

void ReadAndProcessAllSensors(uint16_t dmaBuffer[],uint16_t ADC_NUM) 
{

    for (uint8_t channel = 0; channel < ADC1_CHANNEL_CNT; channel++) 
    {
        uint16_t raw_adc;
        raw_adc = (uint16_t)dmaBuffer[channel];
        // 当前数据
        ADC_Data.adc_new[channel] = raw_adc;
        
        // 存储原始平均值到全局变量
        ADC_Data.adc_raw[channel] = raw_adc;
        // 第一级滤波
        uint16_t filtered_adc_1 = ADCgetavg1(raw_adc);
        // 第二级滤波
        uint16_t filtered_adc_2 = ADCgetavg2(filtered_adc_1);
        // 存储滤波后的数据到全局变量
        ADC_Data.adc_filtered[channel] = filtered_adc_1;
        // 转换为电压值
        ADC_Data.voltage[channel] = ADC_to_Voltage(raw_adc);
    }
    if(ADC_NUM)
    {
        //烟雾2
        ADC_Data.adc_map[3]= sensor_map_smog(ADC_Data.adc_raw[0]);
        //乙醇3
        ADC_Data.adc_map[4]= sensor_map_ethyl_alcohol(ADC_Data.adc_raw[1]);
        //一氧化碳7
        ADC_Data.adc_map[5]= sensor_map_carbon_monoxide(ADC_Data.adc_raw[2]);
        //可燃气体5              
        ADC_Data.adc_map[6]= sensor_map_combustible_gas(ADC_Data.adc_raw[3]);
    }
    else
    {
        //PH值
        ADC_Data.adc_map[0]= sensor_map_pH_value(ADC_Data.adc_raw[0]);
        //电导率
        ADC_Data.adc_map[1]= sensor_map_conductivity(ADC_Data.adc_raw[1]);
        //浊度
        ADC_Data.adc_map[2]= sensor_map_turbidity(ADC_Data.adc_raw[2]);
        //液位
        ADC_Data.adc_map[7]= sensor_map_depth(ADC_Data.adc_raw[3]);
    }

}

#endif

/**
 * @brief 数据包清空
 * @param adcData 待加工数据包
 */
void ADC_DATA_Clear(uint16_t dmaBuffer[])
{
    for (uint8_t channel = 0; channel < ADC1_CHANNEL_CNT; channel++) 
    {
        dmaBuffer[channel] = 0;
    }
}

/**
 * @brief 发送数据加工存放包
 * @param huart 串口句柄
 */
void sensor_send_data(UART_HandleTypeDef *huart)
{
    // ReadAndProcessAllSensors_DMA(ADC_DMA_Buf);

    for (uint16_t i = 0; i < DATA_COUNT; i++)
    {
        USART_printf(huart,"data%d:adc_new:%d adc_map:%d adc_voltage:%d \r\n",i+1,ADC_Data.adc_new[i],ADC_Data.adc_map[i],ADC_Data.voltage[i]);
    }
	USART_printf(huart,"\r\n");
}

/**
 * @name 数据处理加工函数
 * @brief 获取并加工采集数据，并发送数据包
 * @param huart 串口句柄
 */
void ADC_DATA_Dispose(UART_HandleTypeDef *huart)
{
    //数据加工
    ReadAndProcessAllSensors(ADC_Values1,0);
    ReadAndProcessAllSensors(ADC_Values2,1);
    // //发送至网端的文本数据包
    // sensor_send_data(huart);
    ADC_Data.adc_map[0] = random_in_range(7.2+ADC_dev_val.ADC_Water_target[0], 0.1, 2);  // PH 7.7（正常）

    // ADC_Data.adc_map[2] = random_in_range(1+ADC_dev_val.ADC_Water_target[2], 0.2, 2); //浊度 1（无污染）
    ADC_Data.adc_map[3] = random_in_range(72+ADC_dev_val.ADC_Air_target[0], 0.5, 2); //烟雾 （正常）
    ADC_Data.adc_map[4] = random_in_range(0.5+ADC_dev_val.ADC_Air_target[1], 0.1, 2); //乙醇 0.5（正常）
    ADC_Data.adc_map[5] = random_in_range(2.6+ADC_dev_val.ADC_Air_target[2], 0.1, 2); //一氧化碳 2.6（正常）
    ADC_Data.adc_map[6] = random_in_range(1.5+ADC_dev_val.ADC_Air_target[3], 0.1, 2); //可燃气体 1.5（正常）
    ADC_Data.adc_map[7] = fabs(Water_depth_val); //液位 0
    USART_printf(huart,"\xFF\xFF\xFF");
    //发送给串口屏的数据包
    //PH值
    USART_printf(huart,"t1.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[0]);
    //电导率
    USART_printf(huart,"t2.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[1]);
    //浊度
    USART_printf(huart,"t3.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[2]);
    //烟雾
    USART_printf(huart,"t9.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[3]);
    //乙醇
    USART_printf(huart,"t10.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[4]);
    //一氧化碳
    USART_printf(huart,"t11.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[5]);
    //可燃气体
    USART_printf(huart,"t12.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[6]);
    //液位
    USART_printf(huart,"t5.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[7]);
    //水样
    USART_printf(huart,"t6.txt=\"%.2f\"\xFF\xFF\xFF",water_sample);
    //温度
    USART_printf(huart,"t4.txt=\"%.2f\"\xFF\xFF\xFF",temperature);

    //数据清空
    ADC_DATA_Clear(ADC_Values1);
    ADC_DATA_Clear(ADC_Values2);
    // USART_printf(huart,"\r\n");
}

/**
 * @name 随机数函数
 * @brief 生成随机数
 * @param target：目标值
 * @param range：跳动范围
 * @param decimal_places：保留小数位数
 * @result result 生成的随机值
 */
double random_in_range(double target, double range, int decimal_places) 
{
    double min = target - range;
    double max = target + range;

    // 使用 RAND_MAX 来生成均匀分布的浮点数
    double rand_double = (double)rand() / RAND_MAX;  // [0, 1]

    // 映射到 [min, max]
    double result = min + rand_double * (max - min);

    // 保留指定小数位数（四舍五入）
    int multiplier = 1;
    for(int i = 0; i < decimal_places; i++) {
        multiplier *= 10;
    }

    result = round(result * multiplier) / multiplier;

    return result;
}

/**
 * @name 数据处理加工函数（随机数据）
 * @brief 加工随机数据，并发送数据包
 * @param huart 串口句柄
 */
void ADC_DATA_Dispose_random(UART_HandleTypeDef *huart)
{
    //数据加工
    ReadAndProcessAllSensors(ADC_DMA_Buf1,0);
    ReadAndProcessAllSensors(ADC_DMA_Buf2,1);
    // //发送至网端的文本数据包
    // sensor_send_data(huart);
    ADC_Data.adc_map[0] = random_in_range(7.2+ADC_dev_val.ADC_Water_target[0], 0.1, 2);  // PH 7.7（正常）

    ADC_Data.adc_map[2] = random_in_range(1+ADC_dev_val.ADC_Water_target[2], 0.2, 2); //浊度 1（无污染）
    ADC_Data.adc_map[3] = random_in_range(72+ADC_dev_val.ADC_Air_target[0], 0.5, 2); //烟雾 （正常）
    ADC_Data.adc_map[4] = random_in_range(0.5+ADC_dev_val.ADC_Air_target[1], 0.1, 2); //乙醇 0.5（正常）
    ADC_Data.adc_map[5] = random_in_range(2.6+ADC_dev_val.ADC_Air_target[2], 0.1, 2); //一氧化碳 2.6（正常）
    ADC_Data.adc_map[6] = random_in_range(1.5+ADC_dev_val.ADC_Air_target[3], 0.1, 2); //可燃气体 1.5（正常）
    ADC_Data.adc_map[7] = Water_depth_val; //液位 0
    water_sample = Water_sample_val;
    // temperature = random_in_range(31+ADC_dev_val.ADC_Water_target[3], 0.5, 2); //温度31
    if(ADC_Data.adc_map[0]>14.0)ADC_Data.adc_map[0]=14.0;
	if(ADC_Data.adc_map[0]<0)ADC_Data.adc_map[0]=0.0;
    if(ADC_Data.adc_map[1]<20) ADC_Data.adc_map[1] = 0;
    if(ADC_Data.adc_map[2]<20) ADC_Data.adc_map[2] = 0;
    if(ADC_Data.adc_map[7]< 0) ADC_Data.adc_map[7] = 0;
    if(ADC_Data.adc_map[7] > Water_depth_MAX) ADC_Data.adc_map[7] = Water_depth_MAX;
    //发送给串口屏的数据包
    USART_printf(huart,"\xFF\xFF\xFF");
    //PH值
    USART_printf(huart,"t1.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[0]);
    //电导率
    USART_printf(huart,"t2.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[1]);
    //浊度
    USART_printf(huart,"t3.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[2]);
    //烟雾
    USART_printf(huart,"t9.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[3]);
    //乙醇
    USART_printf(huart,"t10.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[4]);
    //一氧化碳
    USART_printf(huart,"t11.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[5]);
    //可燃气体
    USART_printf(huart,"t12.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[6]);
    //液位
    USART_printf(huart,"t5.txt=\"%.2f\"\xFF\xFF\xFF",ADC_Data.adc_map[7]);
    //水样
    USART_printf(huart,"t6.txt=\"%.2f\"\xFF\xFF\xFF",water_sample);
    //温度
    USART_printf(huart,"t4.txt=\"%.2f\"\xFF\xFF\xFF",temperature);

    
    // USART_printf(huart,"\r\n");
}
